package com.tabnet.dao;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

import com.tabnet.dao.impl.AccessoireCMDDAOImpl;
import com.tabnet.dao.impl.AccessoireDAOImpl;
import com.tabnet.dao.impl.AdresseDAOImpl;
import com.tabnet.dao.impl.AppelOffreDAOImpl;
import com.tabnet.dao.impl.CategorieDAOImpl;
import com.tabnet.dao.impl.ClientDAOImpl;
import com.tabnet.dao.impl.CommandeDAOImpl;
import com.tabnet.dao.impl.EtatDAOImpl;
import com.tabnet.dao.impl.FournisseurDAOImpl;
import com.tabnet.dao.impl.GammeProduitDAOImpl;
import com.tabnet.dao.impl.GestionnaireDAOImpl;
import com.tabnet.dao.impl.LigneCommandeDAOImpl;
import com.tabnet.dao.impl.OptionCMDDAOImpl;
import com.tabnet.dao.impl.OptionDAOImpl;
import com.tabnet.dao.impl.ProduitCMDDAOImpl;
import com.tabnet.dao.impl.ProduitDAOImpl;
import com.tabnet.dao.impl.PropositionGammeDAOImpl;

public class DAOFactory {
	
	private static final String FICHIER_PROPERTIES       = "/com/tabnet/dao/dao.properties";
    private static final String PROPERTY_URL             = "url";
    private static final String PROPERTY_DRIVER          = "driver";
    private static final String PROPERTY_NOM_UTILISATEUR = "nomutilisateur";
    private static final String PROPERTY_MOT_DE_PASSE    = "motdepasse";

    private String url;
    private String username;
    private String password;

    DAOFactory( String url, String username, String password ) {
        this.url = url;
        this.username = username;
        this.password = password;
    }

    /**
     * Méthode chargée de récupérer les informations de connexion à la base de
     * données, charger le driver JDBC et retourner une instance de la Factory.
     * @return DAOFactory
     * @throws DAOException
     */
    public static DAOFactory getInstance() throws DAOException {
        Properties properties = new Properties();
        String url;
        String driver;
        String nomUtilisateur;
        String motDePasse;

        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        InputStream fichierProperties = classLoader.getResourceAsStream( FICHIER_PROPERTIES );

        if ( fichierProperties == null ) {
            throw new DAOException( "Le fichier properties " + FICHIER_PROPERTIES + " est introuvable." );
        }

        try {
            properties.load( fichierProperties );
            url = properties.getProperty( PROPERTY_URL );
            driver = properties.getProperty( PROPERTY_DRIVER );
            nomUtilisateur = properties.getProperty( PROPERTY_NOM_UTILISATEUR );
            motDePasse = properties.getProperty( PROPERTY_MOT_DE_PASSE );
        } catch ( IOException e ) {
            throw new DAOException( "Impossible de charger le fichier properties " + FICHIER_PROPERTIES, e );
        }

        try {
            Class.forName( driver );
        } catch ( ClassNotFoundException e ) {
            throw new DAOException( "Le driver est introuvable dans le classpath.", e );
        }

        return new DAOFactory( url, nomUtilisateur, motDePasse );
    }

    /**
     * Méthode chargée de fournir une connexion à la base de données
     * @return Connection
     * @throws SQLException
     */
    public Connection getConnection() throws SQLException {
        return DriverManager.getConnection( url, username, password );
    }
    
    /**
     * Retourne une instance de l'objet DAO
     * @return AdresseDAOImpl
     */
    public AdresseDAOImpl getAdresseDAO(){
    	return new AdresseDAOImpl(this);
    }
    
    /**
     * Retourne une instance de l'objet DAO
     * @return FournisseurDAOImpl
     */
    public FournisseurDAOImpl getFournisseurDAO(){
    	return new FournisseurDAOImpl(this);
    }
    
    /**
     * Retourne une instance de l'objet DAO
     * @return AppelOffreDAOImpl
     */
    public AppelOffreDAOImpl getAppelOffreDAO(){
    	return new AppelOffreDAOImpl(this);
    }
    
    /**
     * Retourne une instance de l'objet DAO
     * @return GammeProduitDAOImpl
     */
    public GammeProduitDAOImpl getGammeProduitDAO(){
    	return new GammeProduitDAOImpl(this);
    }
    
    /**
     * Retourne une instance de l'objet DAO
     * @return ProduitDAOImpl
     */
    public ProduitDAOImpl getProduitDAO(){
    	return new ProduitDAOImpl(this);
    }
    
    /**
     * Retourne une instance de l'objet DAO
     * @return PropositionGammeDAOImpl
     */
    public PropositionGammeDAOImpl getPropositionGammeDAO(){
    	return new PropositionGammeDAOImpl(this);
    }
    
    /**
     * Retourne une instance de l'objet DAO
     * @return EtatDAOImpl
     */
    public EtatDAOImpl getEtatDAO(){
    	return new EtatDAOImpl(this);
    }
    
    /**
     * Retourne une instance de l'objet DAO
     * @return CategorieDAOImpl
     */
    public CategorieDAOImpl getCategorieDAO(){
    	return new CategorieDAOImpl(this);
    }
    
    /**
     * Retourne une instance de l'objet DAO
     * @return OptionDAOImpl
     */
    public OptionDAOImpl getOptionDAO(){
    	return new OptionDAOImpl(this);
    }
    
    /**
     * Retourne une instance de l'objet DAO
     * @return AccessoireDAOImpl
     */
    public AccessoireDAOImpl getAccessoireDAO(){
    	return new AccessoireDAOImpl(this);
    }
    
    /**
     * Retourne une instance de l'objet DAO
     * @return AccessoireDAOImpl
     */
    public GestionnaireDAOImpl getGestionnaireDAO(){
    	return new GestionnaireDAOImpl(this);
    }
    
    /**
     * <p>Fonction getClientDAO<br />
     * Retourne une instance de l'objet DAO</p>
     * @return une instance ClientDAOImpl
     */
    public DAOClient getClientDAO() {
        return new ClientDAOImpl( this );
    }

    /**
     * <p>Fonction getAccessoireCMDDAO<br />
     * Retourne une instance de l'objet DAO</p>
     * @return une instance AccessoireCMDDAOImpl
     */
    public DAOAccessoireCMD getAccessoireCMDDAO() {
        return new AccessoireCMDDAOImpl( this );
    }

    /**
     * <p>Fonction getOptionCMDDAO<br />
     * Retourne une instance de l'objet DAO</p>
     * @return une instance OptionCMDDAOImpl
     */
    public DAOOptionCMD getOptionCMDDAO() {
        return new OptionCMDDAOImpl( this );
    }
    
    /**
     * <p>Fonction getCommandeDAO<br />
     * Retourne une instance de l'objet DAO</p>
     * @return une instance CommandeDAOImpl
     */
    public DAOCommande getCommandeDAO() {
        return new CommandeDAOImpl( this );
    }
    
    /**
     * <p>Fonction getLigneCommandeDAO<br />
     * Retourne une instance de l'objet DAO</p>
     * @return une instance LigneCommandeDAOImpl
     */
    public DAOLigneCommande getLigneCommandeDAO() {
        return new LigneCommandeDAOImpl( this );
    }
    
    /**
     * <p>Fonction getProduitCMDDAO<br />
     * Retourne une instance de l'objet DAO</p>
     * @return une instance ProduitCMDDAOImpl
     */
    public DAOProduitCMD getProduitCMDDAO() {
        return new ProduitCMDDAOImpl( this );
    }
}
